home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
multiuser
/
extern
/
netmufs1.1
/
accounts
/
accounts.c
next >
Wrap
C/C++ Source or Header
|
1994-03-07
|
21KB
|
885 lines
/*
** $VER: accounts.c 1.2 (07.02.94)
**
** accounts.library functions
**
** © Copyright 1994 by Norbert Püschel
** All Rights Reserved
*/
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/multiuser.h>
#include <clib/accounts_protos.h>
#include <pragmas/accounts_pragmas.h>
#include <clib/alib_protos.h>
#include <exec/memory.h>
#include <exec/alerts.h>
#include <dos/notify.h>
#include <envoy/errors.h>
#include <string.h>
#include <debug.h>
#define NOBODY
#ifdef NOBODY
const UBYTE nobody[] = "nobody";
#define NOBODYNAME (STRPTR)nobody
#endif
#define BUFFLEN 256
#define UNAMELEN 32
#define GNAMELEN 32
#define PWDLEN 16
extern struct Library *AccountsBase;
/* accounts.library guardian process */
extern volatile struct Process *guardian;
struct MinList UserList;
struct SignalSemaphore UserSemaphore;
struct MinList GroupList;
struct SignalSemaphore GroupSemaphore;
struct InternalUserInfo {
struct MinNode iui_Node;
struct UserInfo iui_UserInfo;
struct MinList iui_SecGroups;
UBYTE iui_CryptPasswd[PWDLEN];
};
struct InternalGroupInfo {
struct MinNode igi_Node;
struct GroupInfo igi_GroupInfo;
};
struct SecGroup {
struct MinNode sg_Node;
struct InternalGroupInfo *sg_IGI;
};
void init_users(void)
{
NewList((struct List *)&UserList);
memset(&UserSemaphore,0,sizeof(struct SignalSemaphore));
InitSemaphore(&UserSemaphore);
}
void init_groups(void)
{
NewList((struct List *)&GroupList);
memset(&GroupSemaphore,0,sizeof(struct SignalSemaphore));
InitSemaphore(&GroupSemaphore);
}
void free_users(void)
{
struct InternalUserInfo *iui;
struct SecGroup *sg;
ObtainSemaphore(&UserSemaphore);
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
while(iui->iui_Node.mln_Succ) {
Remove((struct Node *)iui);
sg = (struct SecGroup *)(iui->iui_SecGroups.mlh_Head);
while(sg->sg_Node.mln_Succ) {
Remove((struct Node *)sg);
FreeMem(sg,sizeof(struct SecGroup));
sg = (struct SecGroup *)(iui->iui_SecGroups.mlh_Head);
}
FreeMem(iui,sizeof(struct InternalUserInfo));
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
}
ReleaseSemaphore(&UserSemaphore);
}
void free_groups(void)
{
struct InternalGroupInfo *igi;
ObtainSemaphore(&GroupSemaphore);
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
while(igi->igi_Node.mln_Succ) {
Remove((struct Node *)igi);
FreeMem(igi,sizeof(struct InternalGroupInfo));
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
}
ReleaseSemaphore(&GroupSemaphore);
}
BOOL adduser(STRPTR uname,UWORD uid,UWORD gid,ULONG flags,STRPTR pwd)
{
struct InternalUserInfo *iui;
iui = (struct InternalUserInfo *)
AllocMem(sizeof(struct InternalUserInfo),MEMF_PUBLIC);
if(iui) {
strncpy(iui->iui_UserInfo.ui_UserName,uname,UNAMELEN);
iui->iui_UserInfo.ui_UserID = uid;
iui->iui_UserInfo.ui_PrimaryGroupID = gid;
iui->iui_UserInfo.ui_Flags = flags;
strncpy(iui->iui_CryptPasswd,pwd,PWDLEN);
NewList((struct List *)&(iui->iui_SecGroups));
AddTail((struct List *)&UserList,(struct Node *)iui);
}
return((BOOL)(iui != 0));
}
BOOL addgroup(STRPTR gname,UWORD gid)
{
struct InternalGroupInfo *igi;
igi = (struct InternalGroupInfo *)
AllocMem(sizeof(struct InternalGroupInfo),MEMF_PUBLIC);
if(igi) {
strncpy(igi->igi_GroupInfo.gi_GroupName,gname,32);
igi->igi_GroupInfo.gi_GroupID = gid;
AddTail((struct List *)&GroupList,(struct Node *)igi);
}
return((BOOL)(igi != 0));
}
BOOL addsecgroup(struct InternalUserInfo *iui,struct InternalGroupInfo *igi)
{
struct SecGroup *sg;
sg = (struct SecGroup *)AllocMem(sizeof(struct SecGroup),MEMF_PUBLIC);
if(sg) {
sg->sg_IGI = igi;
AddTail((struct List *)&(iui->iui_SecGroups),(struct Node *)sg);
}
return((BOOL)(sg != 0));
}
STRPTR nextsep(STRPTR s,UBYTE sep)
{
while(*s && *s != '\n' && *s != sep) s++;
return(s);
}
struct InternalUserInfo *finduid(UWORD uid)
{
struct InternalUserInfo *iui;
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
while(iui->iui_Node.mln_Succ) {
if(iui->iui_UserInfo.ui_UserID == uid) return(iui);
iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
}
return(0);
}
struct InternalGroupInfo *findgid(UWORD gid)
{
struct InternalGroupInfo *igi;
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
while(igi->igi_Node.mln_Succ) {
if(igi->igi_GroupInfo.gi_GroupID == gid) return(igi);
igi = (struct InternalGroupInfo *)(igi->igi_Node.mln_Succ);
}
return(0);
}
struct InternalUserInfo *finduname(STRPTR uname)
{
struct InternalUserInfo *iui;
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
while(iui->iui_Node.mln_Succ) {
if(strcmp(iui->iui_UserInfo.ui_UserName,uname) == 0) return(iui);
iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
}
return(0);
}
struct InternalGroupInfo *findgname(STRPTR gname)
{
struct InternalGroupInfo *igi;
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
while(igi->igi_Node.mln_Succ) {
if(strcmp(igi->igi_GroupInfo.gi_GroupName,gname) == 0) return(igi);
igi = (struct InternalGroupInfo *)(igi->igi_Node.mln_Succ);
}
return(0);
}
struct InternalUserInfo *finduser(STRPTR uname,UWORD uid)
{
struct InternalUserInfo *iui;
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
while(iui->iui_Node.mln_Succ) {
if(iui->iui_UserInfo.ui_UserID == uid &&
strcmp(iui->iui_UserInfo.ui_UserName,uname) == 0) return(iui);
iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
}
return(0);
}
struct InternalGroupInfo *findgroup(STRPTR gname,UWORD gid)
{
struct InternalGroupInfo *igi;
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
while(igi->igi_Node.mln_Succ) {
if(igi->igi_GroupInfo.gi_GroupID == gid &&
strcmp(igi->igi_GroupInfo.gi_GroupName,gname) == 0) return(igi);
igi = (struct InternalGroupInfo *)(igi->igi_Node.mln_Succ);
}
return(0);
}
BOOL issecmem(struct InternalUserInfo *iui,struct InternalGroupInfo *igi)
{
struct SecGroup *sg;
sg = (struct SecGroup *)(iui->iui_SecGroups.mlh_Head);
while(sg->sg_Node.mln_Succ) {
if(sg->sg_IGI == igi) return(TRUE);
sg = (struct SecGroup *)(sg->sg_Node.mln_Succ);
}
return(FALSE);
}
void read_users(void)
{
BPTR passwd;
UBYTE buff[BUFFLEN];
STRPTR s,pwd,uidstr,gidstr;
ULONG flags = 0;
LONG uid,gid;
ObtainSemaphore(&UserSemaphore);
#ifdef NOBODY
if(!adduser(NOBODYNAME,0,0,0,"")) return;
#endif
passwd = Open(muPasswd_FileName,MODE_OLDFILE);
if(passwd) {
while(FGets(passwd,buff,BUFFLEN-1)) {
s = nextsep(buff,'|');
if(*s != '|') break;
*(s++) = '\0';
pwd = s;
s = nextsep(pwd,'|');
if(*s != '|') break;
if(s != pwd) flags = UFLAGF_NeedsPassword;
*(s++) = '\0';
uidstr = s;
s = nextsep(uidstr,'|');
if(*s != '|') break;
*(s++) = '\0';
gidstr = s;
s = nextsep(gidstr,'|');
if(*s != '|') break;
*s = '\0';
if(StrToLong(uidstr,&uid) <= 0) break;
if(StrToLong(gidstr,&gid) <= 0) break;
flags |= UFLAGF_AdminPassword; /* should evaluate config !!! */
if(uid == muROOT_UID) flags |= (UFLAGF_AdminGroups|UFLAGF_AdminAll);
if(!adduser(buff,uid,gid,flags,pwd)) break;
}
Close(passwd);
}
ReleaseSemaphore(&UserSemaphore);
}
void read_groups(void)
{
BPTR group;
UBYTE buff[BUFFLEN];
STRPTR s,uidstr,gidstr;
LONG uid,gid;
struct InternalGroupInfo *igi;
struct InternalUserInfo *iui;
BOOL done;
ObtainSemaphore(&UserSemaphore);
ObtainSemaphore(&GroupSemaphore);
group = Open(muGroup_FileName,MODE_OLDFILE);
if(group) {
while(FGets(group,buff,BUFFLEN-1) && *buff != ' ' && *buff != '\n') {
s = nextsep(buff,'|');
if(*s != '|') break;
*(s++) = '\0';
gidstr = s;
s = nextsep(gidstr,'|');
if(*s != '|') break;
*s = '\0';
if(StrToLong(gidstr,&gid) <= 0) break;
if(!addgroup(buff,gid)) break;
}
while(FGets(group,buff,BUFFLEN-1)) { /* secondary groups */
s = nextsep(buff,':');
if(*s != ':') break;
*(s++) = '\0';
if(StrToLong(buff,&gid) <= 0) break;
igi = findgid(gid);
if(gid) {
do {
uidstr = s;
s = nextsep(uidstr,',');
done = (*s != ',');
*(s++) = '\0';
if(StrToLong(uidstr,&uid) <= 0) break;
iui = finduid(uid);
if(iui) {
if(!addsecgroup(iui,igi)) break;
}
} while(!done);
}
}
Close(group);
}
ReleaseSemaphore(&GroupSemaphore);
ReleaseSemaphore(&UserSemaphore);
}
void __saveds guardian_func(void)
{
struct muBase *muBase;
struct NotifyRequest *passwd_req;
struct NotifyRequest *group_req;
BYTE passwd_sig,group_sig;
BPTR passwd_dir,olddir;
BOOL sok = FALSE,pok,gok;
struct Message *msg;
struct DosPacket *dp;
struct MsgPort *port;
ULONG mask,rmask,pmask,gmask;
port = &(((struct Process *)FindTask(0))->pr_MsgPort);
WaitPort(port);
msg = GetMsg(port);
debug("Startup Message received !\n");
if(msg == 0 || (dp = (struct DosPacket *)(msg->mn_Node.ln_Name)) == 0) {
Alert(AN_Unknown);
Wait(0); /* not much that I can do here */
}
init_users();
init_groups();
muBase = (struct muBase *)OpenLibrary(MULTIUSERNAME,MULTIUSERVERSION);
if(muBase) {
passwd_dir = muGetPasswdDirLock();
CloseLibrary((struct Library *)muBase);
}
else {
UBYTE buff[256];
if(GetVar("PASSWDDIR",buff,256,0) != -1) {
passwd_dir = Lock(buff,SHARED_LOCK);
}
else {
passwd_dir = Lock("S:",SHARED_LOCK);
}
}
if(passwd_dir) {
debug("Passwd dir found !\n");
olddir = CurrentDir(passwd_dir);
passwd_sig = AllocSignal(-1);
if(passwd_sig != -1) {
group_sig = AllocSignal(-1);
if(group_sig != -1) {
debug("Signals allocated !\n");
passwd_req = (struct NotifyRequest *)
AllocMem(sizeof(struct NotifyRequest),MEMF_PUBLIC|MEMF_CLEAR);
if(passwd_req) {
group_req = (struct NotifyRequest *)
AllocMem(sizeof(struct NotifyRequest),MEMF_PUBLIC|MEMF_CLEAR);
if(group_req) {
debug("Notifiers allocated !\n");
passwd_req->nr_Name = muPasswd_FileName;
passwd_req->nr_Flags = NRF_SEND_SIGNAL;
passwd_req->nr_stuff.nr_Signal.nr_Task = FindTask(0);
passwd_req->nr_stuff.nr_Signal.nr_SignalNum = passwd_sig;
group_req->nr_Name = muGroup_FileName;
group_req->nr_Flags = NRF_SEND_SIGNAL;
group_req->nr_stuff.nr_Signal.nr_Task = FindTask(0);
group_req->nr_stuff.nr_Signal.nr_SignalNum = group_sig;
pok = StartNotify(passwd_req);
gok = StartNotify(group_req);
read_users();
read_groups();
sok = TRUE;
dp->dp_Res1 = DOSTRUE;
PutMsg(dp->dp_Port,msg); /* reply startup */
pmask = 1L << passwd_sig;
gmask = 1L << group_sig;
mask = pmask | gmask | SIGBREAKF_CTRL_C;
debug("Starting Loop !\n");
for(;;) {
rmask = Wait(mask);
if(rmask & SIGBREAKF_CTRL_C) break;
if(rmask & pmask) {
debug("New Users !\n");
ObtainSemaphore(&UserSemaphore);
free_users();
read_users();
ReleaseSemaphore(&UserSemaphore);
}
if(rmask & gmask) {
debug("New Groups !\n");
ObtainSemaphore(&GroupSemaphore);
free_groups();
read_groups();
ReleaseSemaphore(&GroupSemaphore);
}
}
debug("Ending Loop !\n");
if(gok) EndNotify(group_req);
if(pok) EndNotify(passwd_req);
FreeMem(group_req,sizeof(struct NotifyRequest));
}
FreeMem(passwd_req,sizeof(struct NotifyRequest));
}
FreeSignal(group_sig);
}
FreeSignal(passwd_sig);
}
UnLock(CurrentDir(olddir));
}
debug("Freeing Userinfo ...\n");
free_users();
debug("Freeing Groupinfo ...\n");
free_groups();
if(!sok) {
dp->dp_Res1 = DOSFALSE;
dp->dp_Res2 = ERROR_NO_FREE_STORE;
PutMsg(dp->dp_Port,msg);
}
debug("Ending Guardian !\n");
Forbid();
guardian = 0;
}
/* allocation functions */
struct UserInfo * __saveds LIBAllocUserInfo(void)
{
debug("AllocUserInfo\n");
return((struct UserInfo *)AllocMem(sizeof(struct UserInfo),MEMF_CLEAR));
}
struct GroupInfo * __saveds LIBAllocGroupInfo(void)
{
debug("AllocGroupInfo\n");
return((struct GroupInfo *)AllocMem(sizeof(struct GroupInfo),MEMF_CLEAR));
}
void __saveds __asm LIBFreeUserInfo(register __a0 struct UserInfo *user)
{
debug3("FreeUserInfo: Name: %s, UID: %ld\n",
user->ui_UserName,user->ui_UserID);
FreeMem(user,sizeof(struct UserInfo));
}
void __saveds __asm LIBFreeGroupInfo(register __a0 struct GroupInfo *group)
{
debug3("FreeGroupInfo: Name: %s, GID: %ld\n",
group->gi_GroupName,group->gi_GroupID);
FreeMem(group,sizeof(struct GroupInfo));
}
/* xxxToyyy functions */
ULONG __saveds __asm LIBNameToUser(register __a0 STRPTR uname,
register __a1 struct UserInfo *user)
{
ULONG retval;
struct InternalUserInfo *iui;
debug("NameToUser\n");
ObtainSemaphoreShared(&UserSemaphore);
#ifdef NOBODY
if(stricmp(NOBODYNAME,uname) == 0) uname = NOBODYNAME; /* normalize */
#endif
iui = finduname(uname);
if(iui) {
*user = iui->iui_UserInfo;
retval = 0;
}
else retval = ENVOYERR_UNKNOWNUSER;
ReleaseSemaphore(&UserSemaphore);
return(retval);
}
ULONG __saveds __asm LIBNameToGroup(register __a0 STRPTR gname,
register __a1 struct GroupInfo *group)
{
ULONG retval;
struct InternalGroupInfo *igi;
debug("NameToGroup\n");
ObtainSemaphoreShared(&GroupSemaphore);
igi = findgname(gname);
if(igi) {
*group = igi->igi_GroupInfo;
retval = 0;
}
else retval = ENVOYERR_UNKNOWNGROUP;
ReleaseSemaphore(&GroupSemaphore);
return(retval);
}
ULONG __saveds __asm LIBIDToUser(register __d0 UWORD uid,
register __a0 struct UserInfo *user)
{
ULONG retval;
struct InternalUserInfo *iui;
debug("IDToUser\n");
ObtainSemaphoreShared(&UserSemaphore);
iui = finduid(uid);
if(iui) {
*user = iui->iui_UserInfo;
retval = 0;
}
else retval = ENVOYERR_UNKNOWNUSER;
ReleaseSemaphore(&UserSemaphore);
return(retval);
}
ULONG __saveds __asm LIBIDToGroup(register __d0 UWORD gid,
register __a0 struct GroupInfo *group)
{
ULONG retval;
struct InternalGroupInfo *igi;
debug("IDToGroup\n");
ObtainSemaphoreShared(&GroupSemaphore);
igi = findgid(gid);
if(igi) {
*group = igi->igi_GroupInfo;
retval = 0;
}
else retval = ENVOYERR_UNKNOWNGROUP;
ReleaseSemaphore(&GroupSemaphore);
return(retval);
}
/* Nextxxx functions */
ULONG __saveds __asm LIBNextUser(register __a0 struct UserInfo *user)
{
ULONG retval = ENVOYERR_LASTUSER;
struct InternalUserInfo *iui;
debug("NextUser\n");
ObtainSemaphoreShared(&UserSemaphore);
if(user->ui_UserID != 0
#ifdef NOBODY
|| stricmp(user->ui_UserName,NOBODYNAME) == 0
#endif
) { /* take next */
iui = finduser(user->ui_UserName,user->ui_UserID);
if(iui) iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
else retval = ENVOYERR_UNKNOWNUSER;
}
else { /* take first */
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
}
if(iui->iui_Node.mln_Succ) {
*user = iui->iui_UserInfo;
retval = 0;
}
ReleaseSemaphore(&UserSemaphore);
return(retval);
}
ULONG __saveds __asm LIBNextGroup(register __a0 struct GroupInfo *group)
{
ULONG retval = ENVOYERR_LASTGROUP;
struct InternalGroupInfo *igi = 0;
debug("NextGroup\n");
ObtainSemaphoreShared(&GroupSemaphore);
if(group->gi_GroupID != 0 || ((igi = findgid(0)) != 0 &&
strcmp(igi->igi_GroupInfo.gi_GroupName,group->gi_GroupName) == 0)) {
if(igi == 0) igi = findgroup(group->gi_GroupName,group->gi_GroupID);
if(igi) igi = (struct InternalGroupInfo *)(igi->igi_Node.mln_Succ);
else retval = ENVOYERR_UNKNOWNGROUP;
}
else { /* take first */
igi = (struct InternalGroupInfo *)(GroupList.mlh_Head);
}
if(igi->igi_Node.mln_Succ) {
*group = igi->igi_GroupInfo;
retval = 0;
}
ReleaseSemaphore(&GroupSemaphore);
return(retval);
}
ULONG __saveds __asm LIBNextMember(register __a0 struct GroupInfo *group,
register __a1 struct UserInfo *user)
{
ULONG retval = ENVOYERR_LASTMEMBER;
struct InternalUserInfo *iui;
struct InternalGroupInfo *igi;
debug("NextMember\n");
ObtainSemaphoreShared(&UserSemaphore);
ObtainSemaphoreShared(&GroupSemaphore);
if(group->gi_GroupID) {
igi = findgid(group->gi_GroupID);
}
else {
igi = findgname(group->gi_GroupName);
if(igi == 0) igi = findgid(0);
}
if(igi) {
*group = igi->igi_GroupInfo;
if(user->ui_UserID != 0
#ifdef NOBODY
|| stricmp(user->ui_UserName,NOBODYNAME) == 0
#endif
) { /* takenext */
iui = finduser(user->ui_UserName,user->ui_UserID);
if(iui) iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
else retval = ENVOYERR_UNKNOWNUSER;
}
else { /* take first */
iui = (struct InternalUserInfo *)(UserList.mlh_Head);
}
while(iui->iui_Node.mln_Succ) {
if(iui->iui_UserInfo.ui_PrimaryGroupID == group->gi_GroupID ||
issecmem(iui,igi)) break;
iui = (struct InternalUserInfo *)(iui->iui_Node.mln_Succ);
}
if(iui->iui_Node.mln_Succ) {
*user = iui->iui_UserInfo;
retval = 0;
}
}
else retval = ENVOYERR_UNKNOWNGROUP;
ReleaseSemaphore(&GroupSemaphore);
ReleaseSemaphore(&UserSemaphore);
return(retval);
}
/* memberof */
ULONG __saveds __asm LIBMemberOf(register __a0 struct GroupInfo *group,
register __a1 struct UserInfo *user)
{
ULONG retval = ENVOYERR_UNKNOWNMEMBER;
struct InternalUserInfo *iui;
struct InternalGroupInfo *igi;
debug("MemberOf\n");
ObtainSemaphoreShared(&UserSemaphore);
ObtainSemaphoreShared(&GroupSemaphore);
if(user->ui_UserID) {
iui = finduid(user->ui_UserID);
}
else {
iui = finduname(user->ui_UserName);
#ifdef NOBODY
if(iui == 0) iui = finduid(0);
#endif
}
if(iui) {
*user = iui->iui_UserInfo;
if(group->gi_GroupID) {
igi = findgid(group->gi_GroupID);
}
else {
igi = findgname(group->gi_GroupName);
if(igi == 0) igi = findgid(0);
}
if(igi) {
*group = igi->igi_GroupInfo;
if(user->ui_PrimaryGroupID == group->gi_GroupID || issecmem(iui,igi)) {
retval = 0;
}
}
else retval = ENVOYERR_UNKNOWNGROUP;
}
else retval = ENVOYERR_UNKNOWNUSER;
ReleaseSemaphore(&GroupSemaphore);
ReleaseSemaphore(&UserSemaphore);
debug2("MemberOf-result: %ld\n",retval);
return(retval);
}
/* encryption & verification */
STRPTR __saveds __asm LIBECrypt(register __a0 STRPTR buff,
register __a1 STRPTR passwd,
register __a2 STRPTR uname)
{
debug3("ECrypt: Name: %s, Pwd: %s\n",uname,passwd);
return(ACrypt(buff,passwd,uname));
}
ULONG __saveds __asm LIBVerifyUser(register __a0 STRPTR uname,
register __a1 STRPTR passwd,
register __a2 struct UserInfo *user)
{
UBYTE buff[16];
debug3("VerifyUser: Name: %s, Pwd: %s\n",uname,passwd);
if(ACrypt(buff,passwd,uname)) {
return(VerifyUserCrypt(uname,buff,user));
}
else {
return(ENVOYERR_NORESOURCES);
}
}
ULONG __saveds __asm LIBVerifyUserCrypt(register __a0 STRPTR uname,
register __a1 STRPTR passwd,
register __a2 struct UserInfo *user)
{
ULONG retval = ENVOYERR_UNKNOWNUSER;
struct InternalUserInfo *iui;
debug3("VerifyUserCrypt: Name: %s, Pwd: %s\n",uname,passwd);
ObtainSemaphoreShared(&UserSemaphore);
#ifdef NOBODY
if(stricmp(NOBODYNAME,uname) == 0) uname = NOBODYNAME; /* normalize */
#endif
iui = finduname(uname);
if(iui && (iui->iui_CryptPasswd[0] == '\0' ||
strcmp(iui->iui_CryptPasswd,passwd) == 0)) {
*user = iui->iui_UserInfo;
retval = 0;
}
ReleaseSemaphore(&UserSemaphore);
debug2("VerifyUserCrypt: %ld\n",retval);
return(retval);
}